﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.IO;
using System.Text;
using System.Xml;

namespace LED_Tester
{
    sealed class ClassAppConfigure : AppConfigureBase
    {
        #region 电源

        static readonly string sourceModeStr = "sourceMode";
        static readonly string sourcePortNameStr = "sourcePortName";
        static readonly string preheatTimeStr = "preheatTime";
        static readonly string voltSetStr = "voltSet";
        static readonly string currSetStr = "currSet";
        
        public int SourceMode
        {
            get { return GetInt(sourceModeStr, 0); }
            set { SetInt(sourceModeStr, value); }
        }
        public string SourcePortName
        {
            get { return GetString(sourcePortNameStr, "COM1"); }
            set { SetString(sourcePortNameStr, value); }
        }
        public int PreheatTime
        {
            get { return GetInt(preheatTimeStr, 300); }
            set { SetInt(preheatTimeStr, value); }
        }
        public double VoltSet
        {
            get { return GetDouble(voltSetStr, 0.1d); }
            set { SetDouble(voltSetStr, value); }
        }
        public double CurrSet
        {
            get { return GetDouble(currSetStr, 0.1d); }
            set { SetDouble(currSetStr, value); }
        }

        #endregion

        #region 控制卡

        static readonly string strVelXCHStr = "strVelXCH";
        static readonly string strVelYCHStr = "strVelYCH";
        static readonly string strVelZCHStr = "strVelZCH";
        static readonly string maxVelXCHStr = "maxVelXCH";
        static readonly string maxVelYCHStr = "maxVelYCH";
        static readonly string maxVelZCHStr = "maxVelZCH";
        static readonly string taccStr = "tacc";
        static readonly string offsetXCHStr = "offsetXCH";
        static readonly string offsetYCHStr = "offsetYCH";
        static readonly string offsetZCHStr = "offsetZCH";
        static readonly string locationZCHStr = "locationZCH";

        public int StrVelXCH
        {
            get { return GetInt(strVelXCHStr, 100); }
            set { SetInt(strVelXCHStr, value); }
        }
        public int StrVelYCH
        {
            get { return GetInt(strVelYCHStr, 100); }
            set { SetInt(strVelYCHStr, value); }
        }
        public int StrVelZCH
        {
            get { return GetInt(strVelZCHStr, 100); }
            set { SetInt(strVelZCHStr, value); }
        }
        public int MaxVelXCH
        {
            get { return GetInt(maxVelXCHStr, 1000); }
            set { SetInt(maxVelXCHStr, value); }
        }
        public int MaxVelYCH
        {
            get { return GetInt(maxVelYCHStr, 1000); }
            set { SetInt(maxVelYCHStr, value); }
        }
        public int MaxVelZCH
        {
            get { return GetInt(maxVelZCHStr, 1000); }
            set { SetInt(maxVelZCHStr, value); }
        }
        public double Tacc
        {
            get { return GetDouble(taccStr, 0.1d); }
            set { SetDouble(taccStr, value); }
        }
        public int OffsetXCH
        {
            get { return GetInt(offsetXCHStr, 0); }
            set { SetInt(offsetXCHStr, value); }
        }
        public int OffsetYCH
        {
            get { return GetInt(offsetYCHStr, 0); }
            set { SetInt(offsetYCHStr, value); }
        }
        public int OffsetZCH
        {
            get { return GetInt(offsetZCHStr, 0); }
            set { SetInt(offsetZCHStr, value); }
        }
        public int LocationZCH
        {
            get { return GetInt(locationZCHStr, 0); }
            set { SetInt(locationZCHStr, value); }
        }

        #endregion

        #region 光谱仪

        static readonly string isAutoAdjustStr = "isAutoAdjust";
        static readonly string intTimeStr = "intTime";
        static readonly string staStr = "STA";
        static readonly string bcwStr = "BCW";

        public bool IsAutoAdjust
        {
            get { return GetBool(isAutoAdjustStr, false); }
            set { SetBool(isAutoAdjustStr, value); }
        }
        public int IntTime
        {
            get { return GetInt(intTimeStr, 10); }
            set { SetInt(intTimeStr, value); }
        }
        public int STA
        {
            get { return GetInt(staStr, 0); }
            set { SetInt(staStr, value); }
        }
        public int BCW
        {
            get { return GetInt(bcwStr, 0); }
            set { SetInt(bcwStr, value); }
        }

        #endregion

        #region 光强板

        static readonly string luxBoardPortNameStr = "luxBoradPortName";
        static readonly string distanceStr = "distance";
        static readonly string luxDarkValueStr = "luxDarkValue";

        public string LuxBoardPortName
        {
            get { return GetString(luxBoardPortNameStr, "COM2"); }
            set { SetString(luxBoardPortNameStr, value); }
        }
        public double Distance
        {
            get { return GetDouble(distanceStr, 0.1d); }
            set { SetDouble(distanceStr, value); }
        }
        public double LuxDarkValue
        {
            get { return GetDouble(luxDarkValueStr, 0d); }
            set { SetDouble(luxDarkValueStr, value); }
        }

        #endregion

        #region 测试

        static readonly string gammaSampleStr = "gammaSample";
        static readonly string gammaRangeStr = "gammaRange";
        static readonly string measSpaceStr = "measSpace";
        static readonly string cycleSpaceStr = "cycleSpace";
        static readonly string timeSpaceStr = "timeSpace";

        static readonly string secondParam0Str = "secondParam0";
        static readonly string secondParam1Str = "secondParam1";
        static readonly string secondParam2Str = "secondParam2";
        static readonly string secondParam3Str = "secondParam3";

        static readonly string luxParamStr = "luxParam";

        public double GammaSample
        {
            get { return GetDouble(gammaSampleStr, 90d); }
            set { SetDouble(gammaSampleStr, value); }
        }
        public double GammaRange
        {
            get { return GetDouble(gammaRangeStr, 1d); }
            set { SetDouble(gammaRangeStr, value); }
        }
        public int MeasSpace
        {
            get { return GetInt(measSpaceStr, 100); }
            set { SetInt(measSpaceStr, value); }
        }
        public int CycleSpace
        {
            get { return GetInt(cycleSpaceStr, 0); }
            set { SetInt(cycleSpaceStr, value); }
        }
        public int TimeSpace
        {
            get { return GetInt(timeSpaceStr, 1000); }
            set { SetInt(timeSpaceStr, value); }
        }

        public double SecondParam0
        {
            get { return GetDouble(secondParam0Str, 0d); }
            set { SetDouble(secondParam0Str, value); }
        }
        public double SecondParam1
        {
            get { return GetDouble(secondParam1Str, 0d); }
            set { SetDouble(secondParam1Str, value); }
        }
        public double SecondParam2
        {
            get { return GetDouble(secondParam2Str, 0d); }
            set { SetDouble(secondParam2Str, value); }
        }
        public double SecondParam3
        {
            get { return GetDouble(secondParam3Str, 1d); }
            set { SetDouble(secondParam3Str, value); }
        }

        public double LuxParam
        {
            get { return GetDouble(luxParamStr, 1d); }
            set { SetDouble(luxParamStr, value); }
        }

        #endregion

        #region 其它

        static readonly string codeStr = "code";

        static readonly string information0Str = "information0";
        static readonly string information1Str = "information1";
        static readonly string information2Str = "information2";
        static readonly string information3Str = "information3";
        static readonly string information4Str = "information4";
        static readonly string information5Str = "information5";

        static readonly string sdcmIndexStr = "sdcmIndex";
        static readonly string rankloStr = "lo";
        static readonly string rankhiStr = "hi";

        public string Code
        {
            get { return GetString(codeStr, "0000"); }
            set { SetString(codeStr, value); }
        }

        public string Information0
        {
            get { return GetString(information0Str, ""); }
            set { SetString(information0Str, value); }
        }
        public string Information1
        {
            get { return GetString(information1Str, ""); }
            set { SetString(information1Str, value); }
        }
        public string Information2
        {
            get { return GetString(information2Str, ""); }
            set { SetString(information2Str, value); }
        }
        public string Information3
        {
            get { return GetString(information3Str, ""); }
            set { SetString(information3Str, value); }
        }
        public string Information4
        {
            get { return GetString(information4Str, ""); }
            set { SetString(information4Str, value); }
        }
        public string Information5
        {
            get { return GetString(information5Str, ""); }
            set { SetString(information5Str, value); }
        }

        public int SDCMIndex
        {
            get { return GetInt(sdcmIndexStr, 0); }
            set { SetInt(sdcmIndexStr, value); }
        }
        public int RankLo
        {
            get { return GetInt(rankloStr, 1); }
            set { SetInt(rankloStr, value); }
        }
        public int RankHi
        {
            get { return GetInt(rankhiStr, 10); }
            set { SetInt(rankhiStr, value); }
        }

        #endregion

        public ClassAppConfigure(string executeFullName)
            : base(executeFullName)
        {

        }
    }

    public abstract class AppConfigureBase
    {
        string configureFileName;
        protected Dictionary<string, string> KeyValues;

        protected AppConfigureBase(string executeFileFullName)
        {
            configureFileName = Path.Combine(Path.GetDirectoryName(executeFileFullName), Path.GetFileNameWithoutExtension(executeFileFullName) + ".xml");
            KeyValues = new Dictionary<string, string>();
            Load();
        }

        void Load()
        {
            KeyValues.Clear();
            try
            {
                var doc = new XmlDocument();
                doc.Load(configureFileName);
                foreach (XmlNode node in doc.DocumentElement.ChildNodes)
                    KeyValues.Add(node.Name, node.InnerText);
            }
            catch
            {
                // 当配置文件不存在时，不应该抛出异常。
                // 此时，派生类应该使用缺省值进行配置。
            }
        }

        public void Save()
        {
            var doc = new XmlDocument();
            doc.LoadXml(Api.XmlFileHeaderString + "<Settings />");
            foreach (var kvp in KeyValues)
            {
                var elem = doc.CreateElement(kvp.Key);
                elem.InnerText = kvp.Value;
                doc.DocumentElement.AppendChild(elem);
            }
            doc.Save(configureFileName);
        }

        protected string GetString(string key, string defaultValue)
        {
            string value;
            if (!KeyValues.TryGetValue(key, out value)) return defaultValue;
            return value;
        }

        protected void SetString(string key, string value)
        {
            KeyValues[key] = value;
        }

        protected long GetInt64(string key, long defalutValue)
        {
            return long.Parse(GetString(key, defalutValue.ToString()));
        }

        protected void SetInt64(string key, long value)
        {
            SetString(key, value.ToString());
        }

        protected float GetFloat(string key, float defalutValue)
        {
            return float.Parse(GetString(key, defalutValue.ToString()));
        }
        
        protected void SetFloat(string key, float value)
        {
            SetString(key, value.ToString());
        }

        protected int GetInt(string key, int defalutValue)
        {
            return int.Parse(GetString(key,defalutValue.ToString()));
        }

        protected void SetInt(string key, int value)
        {
            SetString(key, value.ToString());
        }

        protected double GetDouble(string key, double defalutValue)
        {
            return double.Parse(GetString(key, defalutValue.ToString()));
        }

        protected void SetDouble(string key, double value)
        {
            SetString(key, value.ToString());
        }

        protected bool GetBool(string key, bool defalutValue)
        {
            return bool.Parse(GetString(key, defalutValue.ToString()));
        }

        protected void SetBool(string key, bool value)
        {
            SetString(key, value.ToString());
        }

        protected uint GetUint(string key, uint defalutValue)
        {
            return uint.Parse(GetString(key, defalutValue.ToString()));
        }

        protected void SetUint(string key, uint value)
        {
            SetString(key, value.ToString());
        }  

        protected DateTime GetDateTime(string key, DateTime defaultValue)
        {
            return DateTime.FromBinary(GetInt64(key, defaultValue.ToBinary()));
        }

        protected void SetDateTime(string key, DateTime value)
        {
            SetInt64(key, value.ToBinary());
        }

        public class Api
        {
            public static string XmlFileHeaderString = @"<?xml version=""1.0"" encoding=""UTF-8""?>";
            public static readonly Encoding GB18030Encoding = Encoding.GetEncoding("GB18030");
        }
    }
}
